﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BuildSDFDatabase
{
	#region Corpora
	public interface ICorporaDataProvider
	{
		DateTime StartTime { get; }
		DateTime EndTime { get; }
		string BaseCorpus { get; }
		Dictionary<string, int> Corpora { get; }	//with order
		Dictionary<string, int> Fields { get; }		//with order

		IEnumerable<TreeNode> GetChildrenWithTopicAmount(string corpus, string field, string parentName);
		
		//corpusContent --> topicCluster, topic
		DateTime GetCorpusContentStartTime(CorpusContent corpusContent);
		DateTime GetCorpusContentEndTime(CorpusContent corpusContent);
		IEnumerable<KeywordDouble> GetCorpusContentSortedTFIDFKeywords(CorpusContent corpusContent, int maxCount);
		
		//return corpusContent leadlagValue compare baseCorpus to referedCorpus
		double GetCorpusContentLeadLag(string field, string corpusContentName, string referedCorpus);
	}

	public class CorpusContent
	{
		public int ID { get; private set; }
		public string Corpus { get; private set; }
		public string Field { get; private set; }

		public DateTime StartTime { get; set; }
		public DateTime EndTime { get; set; }
	}

	public class TopicCluster : CorpusContent
	{
		public CorpusContent[] Children;
		public Topic[] ContainedTopics;
	}

	public class Topic : CorpusContent
	{
		
	}

	public class TreeNode
	{
		public string Name { get; private set; }
		public int ContainedTopicNumber { get; private set; }

		public TreeNode(string name, int count)
		{
			Name = name;
			ContainedTopicNumber = count;
		}
	}

	public class KeywordDouble
	{
		public string Keyword { get; private set; }
		public double Value { get; private set; }

		public KeywordDouble(string k, double v)
		{
			Keyword = k;
			Value = v;
		}
	}
	#endregion

	#region Topics
	public interface ITopicsDataProvider
	{
		IEnumerable<CoupleCorporaTimeValue> GetTopicLeadLagValues(string field, int topicId, string corpus1, string corpus2);
	}

	public class CoupleCorporaTimeValue
	{
		public DateTime Timestamp { get; private set; }
		public string Corpus1 { get; private set; }
		public string Corpus2 { get; private set; }
		public double Value1 { get; private set; }
		public double Value2 { get; private set; }

		public CoupleCorporaTimeValue(DateTime timestamp, string corpus1, string corpus2, double value1, double value2)
		{
			Timestamp = timestamp;
			Corpus1 = corpus1;
			Corpus2 = corpus2;
			Value1 = value1;
			Value2 = value2;
		}
	}
	#endregion

	#region Alignment
	public interface IAlignmentDataProvider
	{
		IEnumerable<CoupleCorporaTimeValue> GetTopicLeadLagValues(string field, int topicId, string corpus1, string corpus2);
		IEnumerable<DocumentPair> GetTopicDocumentMatrix(string field, int topicId, string corpus1, string corpus2);
		TopicDocumentDistribute GetTopicDocumentDistribute(Topic topic);
	}

	public class DocumentPair
	{
		public int DocumentID1 { get; private set; }
		public int DocumentID2 { get; private set; }
		public double Similarity { get; private set; }

		public DocumentPair(int docID1, int docID2, double similarity)
		{
			DocumentID1 = docID1;
			DocumentID2 = docID2;
			Similarity = similarity;
		}
	}

	public class TopicDocumentDistribute
	{
		Topic Topic { get; private set; }
		DateTime[] Timestamps { get; private set; }
		int[] DocumentAmount { get; private set; }
	}

	#endregion

	#region Entities
	/// <summary>
	/// Suppose to hind corpus/field/topic in Entities and Keywords, or do we need to explictly use this parameters?
	/// </summary>
	public interface IEntitiesDataProvider
	{
		IEnumerable<string> GetEntityTypes();
		//objectId compose by corpus + field + topicId
		//IEnumerable<Tuple<DateTime, List<int>>> GetObjectDisplayListByEntityType(string objectId, string entityTypeName);
		IEnumerable<Entity> GetEntities(string typeName, DateTime startDate, DateTime endDate);
	}

	public abstract class Entity
	{
		public string DisplayContent { get; private set; }

		public Entity(string content)
		{
			DisplayContent = content;
		}
	}
	#endregion

	#region Keywords
	public interface IKeywordsDataProvider
	{
		//topic keywords with frequency, centerId compose by corpus + field + topicId
		IEnumerable<KeywordInt> GetCenterSortedTFkeywords(string centerId, int maxCount);
	}

	public class KeywordInt
	{
		public string Keyword { get; private set; }
		public int Value { get; private set; }

		public KeywordInt(string k, int v)
		{
			Keyword = k;
			Value = v;
		}
	}
	#endregion
}

